package cn.wolfcode.core;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

/**
 * @author BAI
 */
@Slf4j
@Component
@ServerEndpoint("/{token}")
public class WebSocketSever {

    private static ConcurrentHashMap<String, Session> SESSION_MAP = new ConcurrentHashMap<>();

    @OnOpen
    public void onOpen(@PathParam("token") String token, Session session) {
        log.info("[建立连接] 当前连接用户:{} ,连接数 {}", token, SESSION_MAP.size()+1);
        SESSION_MAP.put(token, session);
    }

    @OnClose
    public void onClose(@PathParam("token") String token, Session session) {
        log.info("[关闭连接] 当前连接用户:{} ,连接数 {}", token, SESSION_MAP.size() -1);
        SESSION_MAP.remove(token);
    }

    @OnError
    public void onError(@PathParam("token") String token,Throwable throwable) {
        log.info("[连接异常] 当前连接用户:{} ,异常信息 {}", token, throwable.getMessage());
        SESSION_MAP.remove(token);
    }

    public static void sendMessage(String token, String message) {
        try {
            Session session =null;
            int count = 0, maxCount = 5;
        do {
           session  = SESSION_MAP.get(token);
            if (session != null) {
                    break;
            }else if (count < maxCount) {
                log.warn("[用户不在线]  重新尝试连接 第{}次", count);
                TimeUnit.SECONDS.sleep(1);
                count++;
            }else {
                log.error("[连接失败]  连接失败 {}次", count);
                break;
            }
        } while (true);
            if (session != null) {
                log.info("[发送消息] 当前连接用户:{} ,消息内容 {}", token, message);
                session.getBasicRemote().sendText(message);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}
